package com.sensorfriendly.ui;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Random;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.sensorfriendly.AppConstants;
import com.sensorfriendly.AppContext;
import com.sensorfriendly.R;
import com.sensorfriendly.model.Message;
import com.sensorfriendly.util.CallUtil;
import com.sensorfriendly.util.ImageUtil;

/**
 * Acitivy for showing/animating message with image if available.
 *
 */
public class MessageActivity extends Activity implements OnInitListener,
		OnClickListener, MediaPlayer.OnCompletionListener {

	private static final int TTS_CHECK = 0;

	private List<Message> messages;
	private Random r;
	private BubbleTextView messageView;
	private ImageView imageView;
	private Integer messageIndex;
	private GestureDetector gesturedetector = null;
	private String category;
	private TextToSpeech myTTS = null;
	private SharedPreferences sharePrefs;
	private boolean flipPage =true;
	private MediaPlayer   mPlayer = null;


	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_messages);
		AppContext app = (AppContext) getApplication();
		r = new Random();
		Bundle extra = this.getIntent().getExtras();
		category = extra.getString(AppConstants.CATEGORY);
		messageIndex = extra.getInt(AppConstants.MESSAGE_INDEX);
		if (messageIndex == null) {
			messageIndex = 0;
		}

		messages = app.getScenarioMessages(category);
		imageView = (ImageView) findViewById(R.id.message_image);
		messageView = (BubbleTextView) findViewById(R.id.message);
		handleGestureListner();
		((TextView) findViewById(R.id.page_title)).setText(category);

		((ImageView) findViewById(R.id.ab_settings)).setOnClickListener(this);
		((ImageView) findViewById(R.id.ab_home)).setOnClickListener(this);
		((ImageView) findViewById(R.id.ab_call)).setOnClickListener(this);
		sharePrefs = PreferenceManager.getDefaultSharedPreferences(this);
		
		if(messages.size()<1){
			Toast.makeText(this, "No messages in this scenario", Toast.LENGTH_LONG).show();
			this.finish();
		}

	}

	protected void onResume() {
		super.onResume();
		String	imageName = messages.get(messageIndex).getMessageImagePath();
		Display display = getWindowManager().getDefaultDisplay(); 
		int screenWidth = display.getWidth();
		int screenHeight = display.getHeight();
		//load image if the message has it
		if(imageName != null){
			Bitmap image = ImageUtil.decodeSampledBitmapFromPath(imageName, screenWidth, screenHeight);
			imageView.setImageBitmap(image);		
		}
		//check if use wants audio prompt
		boolean audioActivated = sharePrefs.getBoolean(
				AppConstants.PREFERENCE_AUDIO_ACTIVATED, true);
		// Use customized recording if it's available otherwise use TTS
		if (audioActivated) {
			if (messages.get(messageIndex).getAudioFile() != null) {
				playCustomAudio();
			}
			else{
				playTTSAudio();
			}
		}
		else{
			messageView.setText(messages.get(messageIndex).getMessageContent());
		}
	}
	
	
	//play TTS genertaed audio
	private void playTTSAudio() {
		if (myTTS == null) {
			// check for TTS data
			Intent checkTTSIntent = new Intent();
			checkTTSIntent
					.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
			startActivityForResult(checkTTSIntent, TTS_CHECK);
			messageView.animateText((messages.get(messageIndex).getMessageContent()));
		}
	}
	//play pre-recorded audio for this message
	private void playCustomAudio() {
		if (mPlayer == null) {
			mPlayer = new MediaPlayer();
			mPlayer.setOnCompletionListener(this);
			try {
				mPlayer.setDataSource(messages.get(messageIndex).getAudioFile());
				mPlayer.prepare();
				mPlayer.start();
				messageView.animateText((messages.get(messageIndex).getMessageContent()), mPlayer.getDuration()-1000);
			} catch (IOException e) {
				Toast.makeText(this, "Problem loading audio file.", Toast.LENGTH_LONG).show();
				playTTSAudio();
			}
		}
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		if (myTTS != null) {
			myTTS.stop();
			myTTS.shutdown();
			myTTS = null;
		}
		
        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
		System.gc();
	}
	
	@Override
	protected void onStop(){
		super.onStop();
        messageView.stopAnimation();
        Log.d("JW", "text animiation stopped");
	}
	

	/*-------------------------------------*
	 * This function is used to setup the  *
	 * Listener to detect "touch" events   *
	 *-------------------------------------*/
	private void handleGestureListner() {
		gesturedetector = new GestureDetector(new MyGestureListener());
		View layout = (RelativeLayout) findViewById(R.id.message_root);
		layout.setOnTouchListener(new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				gesturedetector.onTouchEvent(event);
				return true;
			}
		});
	}

	public boolean dispatchTouchEvent(MotionEvent ev) {
		super.dispatchTouchEvent(ev);
		return gesturedetector.onTouchEvent(ev);
	}
	
	//show the next message
	private int nextMessage() {
		messageIndex = (messageIndex + 1) % messages.size();
		return messageIndex;
	}
	
	// show previous message
	private int previousMessage() {
		if (messageIndex == 0) {
			messageIndex = messages.size() - 1;
		} else {
			messageIndex = (messageIndex - 1) % messages.size();
		}
		return messageIndex;
	}
	
	
	//Checking availabe TTS
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == TTS_CHECK) {
			if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
				myTTS = new TextToSpeech(this, this);
			} else {
//				Toast.makeText(this, "Speech data not available",
//						Toast.LENGTH_LONG).show();
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	// setup TTS
	public void onInit(int initStatus) {
		// check for successful instantiation
		if (initStatus == TextToSpeech.SUCCESS && myTTS != null) {
			if (myTTS.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE)
				myTTS.setLanguage(Locale.US);
			myTTS.speak(messages.get(messageIndex).getMessageContent(), TextToSpeech.QUEUE_FLUSH,
					null);
		} else if (initStatus == TextToSpeech.ERROR) {
			Toast.makeText(this, "Sorry! Text To Speech failed...",
					Toast.LENGTH_LONG).show();
		}
	}
	
	
	// click listner for action bar items
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.ab_settings:
			Intent settingsIntent = new Intent(this, SettingsActivity.class);
			startActivity(settingsIntent);
			break;
		case R.id.ab_call:
			String phoneNum = PreferenceManager.getDefaultSharedPreferences(this).getString(AppConstants.PREFERENCE_EMERGENCY_NUMBER, "");
			if(phoneNum.length()>1){
				CallUtil.call(this, phoneNum);
			}
			break;
		case R.id.ab_home:
			Intent homeIntent = new Intent(this, DashboardNavigationActivity.class);
			homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
					| Intent.FLAG_ACTIVITY_SINGLE_TOP);
			startActivity(homeIntent);
			break;
		}
	}
	
	
	// animate to the previous message
	private void previous() {
		messageIndex = previousMessage();
		Intent previousPage = new Intent(getApplicationContext(),
				MessageActivity.class);
		previousPage.putExtra(AppConstants.CATEGORY, category);
		previousPage.putExtra(AppConstants.MESSAGE_INDEX, messageIndex);
		startActivity(previousPage);
		overridePendingTransition(R.anim.slide_right_incoming,
				R.anim.slide_right_outgoing);
		finish();
	}

	// animate to the next message
	private void next() {
		messageIndex = nextMessage();
		Intent nextPage = new Intent(getApplicationContext(),
				MessageActivity.class);
		nextPage.putExtra(AppConstants.CATEGORY, category);
		nextPage.putExtra(AppConstants.MESSAGE_INDEX, messageIndex);
		startActivity(nextPage);
		overridePendingTransition(R.anim.slide_left_incoming,
				R.anim.slide_left_outgoing);
		finish();
	}

	/*---------------------------------------------*
	 * The Gesture class that detects the gesture  *
	 * and determines if it is appropriate enough  *
	 * to be considered a left/right swipe         *
	 *---------------------------------------------*/
	class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

		private static final int SWIPE_MIN_DISTANCE = 30;
		private static final int SWIPE_MAX_OFF_PATH = 250;
		private static final int SWIPE_THRESHOLD_VELOCITY = 30;

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {

			float dX = e2.getX() - e1.getX();
			float dY = e1.getY() - e2.getY();

			if (Math.abs(dY) < SWIPE_MAX_OFF_PATH
					&& Math.abs(velocityX) >= SWIPE_THRESHOLD_VELOCITY
					&& Math.abs(dX) >= SWIPE_MIN_DISTANCE) {

				if (dX > 0) {
					if(flipPage){
						flipPage=false;
						previous();
					}
				} else {
					if(flipPage){
						flipPage=false;
						next();
					}
				}
				return true;
			}
			return false;
		}
	} // End MyGestureListner class

	@Override
	public void onCompletion(MediaPlayer mp) {
		  mPlayer.release();
	      mPlayer = null;
	}

}